package com.boot.demo.realm;

import com.boot.demo.bean.UserInfo;
import com.boot.demo.dao.SysPermissionDao;
import com.boot.demo.dao.SysRoleDao;
import com.boot.demo.dao.UserInfoDao;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class MyRealm extends AuthorizingRealm  {
    @Autowired
    private UserInfoDao userInfoDao;
    @Autowired
    private SysRoleDao sysRoleDao;
    @Autowired
    private SysPermissionDao sysPermissionDao;

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken token= (UsernamePasswordToken) authenticationToken;
        String username = token.getUsername();
        UserInfo userInfo = userInfoDao.getByUsername(username);
        //5根据用户的情况，来构建AuthenticationInfo对象并返回，通常实现类为SimpleAuthenticationInfo
        //（1）principal认证的实体信息，可以使username也可以是实体类
        Object principal=userInfo;

        if (userInfo==null){
            throw new UnknownAccountException("没有用户信息");
        }
        if ("1".equals(userInfo.getState())){
            throw new LockedAccountException("用户已被锁住");
        }
        //（2）credentials 密码
        Object credentials=userInfo.getSalt();
        //（3）realmName 当前realm对象的name 调用父类的getName()
        String realmName=getName();
        //（4）MD5盐值加密 区分添加用户名，区分相同的密码 更加安全 一般使用唯一
        ByteSource salt = ByteSource.Util.bytes(username);                       //1数据库信息 2数据库密码或加盐密码  3给前台密码加盐 4realm名字
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(principal,  userInfo.getSalt(), salt, realmName);
        return authenticationInfo;
    }
    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        Object principal = principalCollection.getPrimaryPrincipal();
        Set<String> roles = sysRoleDao.getRolesByUser((UserInfo) principal);
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(roles);
        Set<String> permissions=new HashSet<>();
        List<Map<Object, Object>> permission = sysPermissionDao.getPermissionByRoles(roles);
        for (Map<Object, Object> map : permission) {
            Object role = map.get("role");
            Object perm = map.get("permission");
            permissions.add(role+":"+perm);
     //  permissions.add(map.get("permission")+"");
        }
        authorizationInfo.setStringPermissions(permissions);
        return authorizationInfo;
    }
}
